﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace lfm.EndPoints
{
    public class Track
    {
        /// <summary>
        /// Get the metadata for a track on Last.fm using the artist/track name
        /// </summary>
        /// <param name="Artist">Artist Name</param>
        /// <param name="Track">Track Name</param>
        /// <param name="Autocorrect">Transform misspelled artist and track names into correct artist and track names, returning the correct version instead. The corrected artist and track name will be returned in the response.</param>
        /// <returns>lfm.Track</returns>
        public static async Task<lfm.Track> getInfo(String Artist, String Track, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=track.getInfo&artist={1}&track={2}", Base.APIUrl, Uri.EscapeDataString(Artist), Uri.EscapeDataString(Track));
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Track.getInfo(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Gets a list of the buy links for a track 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Track">The track name</param>
        /// <param name="Country">A country name, as defined by the ISO 3166-1 country names standard.</param>
        /// <param name="Autocorrect">Transform misspelled artist and track names into correct artist and track names, returning the correct version instead. The corrected artist and track name will be returned in the response.</param>
        /// <returns>Buy links for this track</returns>
        public static async Task<List<lfm.Link>> getBuyLinks(String Artist, String Track, String Country, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=track.getbuylinks&artist={1}&track={2}&country={3}", Base.APIUrl, Uri.EscapeDataString(Artist), Uri.EscapeDataString(Track), Uri.EscapeDataString(Country));
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Generic.getBuyLinks(await Base.DownloadString(u));
        }

        /// <summary>
        /// Get the similar tracks for this track on Last.fm, based on listening data. 
        /// </summary>
        /// <param name="Artist">Artist Name</param>
        /// <param name="Track">Track Name</param>
        /// <param name="Limit">Maximum number of similar tracks to return</param>
        /// <param name="Autocorrect">Transform misspelled artist and track names into correct artist and track names, returning the correct version instead. The corrected artist and track name will be returned in the response.</param>
        /// <returns>List of lfm.Track</returns>
        public static async Task<List<lfm.Track>> getSimilar(String Artist, String Track, Int32? Limit, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=track.getSimilar&artist={1}&track={2}", Base.APIUrl, Uri.EscapeDataString(Artist), Uri.EscapeDataString(Track));
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Track.getSimilar(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Gets a list of shouts for a Track
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Track">The Track name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <param name="Autocorrect">Transform misspelled artist and track names into correct artist and track names, returning the correct version instead. The corrected artist and track name will be returned in the response.</param>
        /// <returns>Shouts for this Track</returns>
        public static async Task<List<lfm.Shout>> getShouts(String Artist, String Track, Int32? Page, Int32? Limit, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=track.getShouts&artist={1}&track={2}", Base.APIUrl, Uri.EscapeDataString(Artist), Uri.EscapeDataString(Track));
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Generic.getShouts(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Gets a list of the most popular tags for  a Track 
        /// </summary>
        /// <param name="Artist">The artist name</param>
        /// <param name="Track">The Track name</param>
        /// <param name="Autocorrect">Transform misspelled artist and track names into correct artist and track names, returning the correct version instead. The corrected artist and track name will be returned in the response.</param>
        /// <returns>Top Track for this album</returns>
        public static async Task<List<lfm.Tag>> getTopTags(String Artist, String Track, Boolean? Autocorrect)
        {
            String s = String.Format("{0}&method=track.gettoptags&artist={1}&track={2}", Base.APIUrl, Uri.EscapeDataString(Artist), Uri.EscapeDataString(Track));
            if (Autocorrect.HasValue && Autocorrect.Value) s += "&autocorrect=1";

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Generic.getTags(await Base.DownloadString(u));
        }

        /// <summary>
        /// Search for a track by track name. Returns track matches sorted by relevance.
        /// </summary>
        /// <param name="Track">The track name</param>
        /// <param name="Artist">OPTIONAL - Narrow your search by specifying an artist.</param>
        /// <param name="Page">The page number to fetch. Defaults to first page</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 30</param>
        /// <returns>List of lfm.Track</returns>
        public static async Task<List<lfm.Track>> search(String Track, String Artist, Int32? Page, Int32? Limit)
        {
            String s = String.Format("{0}&method=track.search&track={1}", Base.APIUrl, Uri.EscapeDataString(Track));
            if (!String.IsNullOrEmpty(Artist)) s += "&artist=" + Uri.EscapeDataString(Artist);
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Track.search(await Base.DownloadString(u));
        }
    }
}
